package com.edu.hre.struts.action.recruit;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.edu.hre.common.utils.BeanFinder;
import com.edu.hre.common.utils.ComboBoxInit;
import com.edu.hre.common.utils.CommonUtils;
import com.edu.hre.common.utils.StringConstants;
import com.edu.hre.db.pojo.HreJobVacancy;
import com.edu.hre.db.pojo.HreJobVacancyAttachment;
import com.edu.hre.db.service.BaseService;
import com.edu.hre.db.utils.Compare;
import com.edu.hre.struts.form.recruit.VacancyUpdateForm;

public class VacancyUpdateAction extends Action {

	private static final Logger logger = Logger.getLogger(VacancyUpdateAction.class);
	private static final BaseService baseService = BeanFinder.getBean(BaseService.BEAN_NAME, BaseService.class);
	private final String ACTION_NAME = "vacancyUpdate";
	
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		CommonUtils.println(CommonUtils.getSourceCodeLocation());
		VacancyUpdateForm beanForm = (VacancyUpdateForm) form;
		beanForm.setIsAddNew(false); 

		if(request.getParameter(StringConstants.BTN_EDIT) == null){

			int id = CommonUtils.getIntParameter("id", request);

			HreJobVacancy tmp = baseService.getFirstPojo("id", Compare.EQUAL, id, null, null, 0, HreJobVacancy.class);
			if (tmp == null) {
				initFormBean(beanForm, request);
				beanForm.setMessage(StringConstants.BLANK);
				beanForm.setSuccess(false);
				return mapping.findForward(ACTION_NAME);
			}

			beanForm.setId(tmp.getId());
			beanForm.setJobTitle(tmp.getJobTitleCode());
			beanForm.setHiringManager(CommonUtils.getEmpNameAndUsername(tmp.getHiringManagerId()));
			beanForm.setName(CommonUtils.normalizeString(tmp.getName()));
			beanForm.setDescription(getDescriptionForUser(tmp.getDescription()));
			getNumerialDescription(beanForm, tmp.getDescription());
			beanForm.setNoOfPositions(CommonUtils.normalizeInteger(tmp.getNoOfPositions()) + StringConstants.BLANK);
			beanForm.setStatus(tmp.getStatus());

			initFormBean(beanForm, request);
			beanForm.setMessage(StringConstants.BLANK);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}
		
		String message = validateForm(beanForm);
		if(!StringUtils.isBlank(message)){
			beanForm.setMessage(message);
			beanForm.setSuccess(false);
			beanForm.setStatus(1);
			initFormBean(beanForm, request);
			return mapping.findForward(ACTION_NAME);
		}
		
		HreJobVacancy tmp = baseService.getFirstPojo("id", Compare.EQUAL, beanForm.getId(), null, null, 0, HreJobVacancy.class);
		if (tmp == null) {
			initFormBean(beanForm, request);
			beanForm.setMessage(StringConstants.BLANK);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}

		tmp.setJobTitleCode(beanForm.getJobTitle());
		int managerId = CommonUtils.getEmpNumber(beanForm.getHiringManager());
		tmp.setHiringManagerId(managerId);
		tmp.setName(CommonUtils.normalizeString(beanForm.getName()));
		tmp.setDescription(getDbDescription(beanForm));
		tmp.setNoOfPositions(getIntegerParam(beanForm.getNoOfPositions()));
		tmp.setStatus(beanForm.getStatus());
		tmp.setDateModified(new Date());

		boolean status = baseService.saveOrUpdate(tmp);
		if (!status) {
			beanForm.setMessage(StringConstants.UPDATE_FAILURE_MESSAGE);
			beanForm.setSuccess(false);
			initFormBean(beanForm, request);
			return mapping.findForward(ACTION_NAME);
		}

		FormFile attachFile = beanForm.getAttachFile();
		if(attachFile != null && StringUtils.isNotBlank(attachFile.getFileName())){
			HreJobVacancyAttachment attach = baseService.getFirstPojo("vacancyId", Compare.EQUAL, tmp.getId(), null, null, 0, HreJobVacancyAttachment.class);
			if(attach == null){
				attach = new HreJobVacancyAttachment();
			}
			attach.setFileType(attachFile.getContentType());
			attach.setVacancyId(tmp.getId());
			attach.setFileSize(attachFile.getFileSize());
			attach.setDateModified(new Date());
			attach.setDateCreated(new Date());
			attach.setFileName(attachFile.getFileName());
			attach.setFileContent(attachFile.getFileData());

			baseService.saveOrUpdate(attach);
		}

		beanForm.setMessage("Vacancy information has been updated successfully!");
		beanForm.setSuccess(true);
		initFormBean(beanForm, request);
		return mapping.findForward(ACTION_NAME);
	}
	
	private void initFormBean(VacancyUpdateForm beanForm, HttpServletRequest request) {

		beanForm.setAllJobTitles(ComboBoxInit.getAllJobTitles(false));
		beanForm.setAllManagers(ComboBoxInit.getAllEmployees(false));
		beanForm.setAllStatuses(ComboBoxInit.getAllActiveStatuses(false));
		beanForm.setAllEducation(ComboBoxInit.getAllEducations(true));
		beanForm.setAllMajors(ComboBoxInit.getAllMajors(true));
		beanForm.setAllLanguages(ComboBoxInit.getAllLanguages(true));
		beanForm.setAllSkills(ComboBoxInit.getAllSkills(true));
		beanForm.setAllLicenses(ComboBoxInit.getAllLicenses(true));
		beanForm.setAllImportanceLevels(ComboBoxInit.getAllImportanceLevels(true));
		beanForm.setAllAdvantageLevels(ComboBoxInit.getAllAdvantageLevels(true));
	}
	
	private int getIntegerParam (String value) {

		int intVal = 0;
		try {
			intVal = Integer.parseInt(value);
		} catch (Exception e) {
			return -1;
		}
		
		return intVal;
	}
	
	private String getDescriptionForUser (String dbDescription) {
		return "Description for users";
	}

	private String getDbDescription (VacancyUpdateForm beanForm) {
		
		String result = StringConstants.BLANK;
		
		for (String key: StringConstants.EVALUATOR_KEYS) {
			result += getKeyValueCouple(key, beanForm);
		}

		return result;
	}
	
	private String getKeyValueCouple (String key, VacancyUpdateForm beanForm) {

		String result = StringConstants.BLANK;
		result += key + ":";
		
		Object result1 = StringConstants.BLANK;

		try {	
			
			String getter = "get"
					+ String.valueOf(key.charAt(0)).toUpperCase()
					+ key.substring(1);
	
			Method method = beanForm.getClass().getMethod(getter);
			result1 = method.invoke(beanForm);

		} catch (Exception e) {
			
		}

		if (result1 != null) {
			result += result1.toString() + ";";
		} else {
			result += "0;";
		}

		return result;
	}
	
	public static void getNumerialDescription (VacancyUpdateForm beanForm, String dbDescription) {
		
		try {

			String[] allCouples = dbDescription.split(";");
	
			if (allCouples == null || allCouples.length <= 0) {
				return;
			}
			
			for (String cou: allCouples) {
				String[] keyVal = cou.split(":");
				if (keyVal == null || keyVal.length != 2) {
					continue;
				}
				
				setKeyValueCouple(keyVal[0], keyVal[1], beanForm);
			}
		} catch (Exception e) {
			
		}
	}
	
	private static void setKeyValueCouple (String key, String value, VacancyUpdateForm beanForm) {

		int val = 0;
		
		try {
			val = Integer.parseInt(value);
		} catch (Exception e) {
			val = 0;
		}

		try {	
			
			String setter = "set"
					+ String.valueOf(key.charAt(0)).toUpperCase()
					+ key.substring(1);
			Method method = beanForm.getClass().getMethod(setter, int.class);
			method.invoke(beanForm, val);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private String validateForm (VacancyUpdateForm beanForm) {
		
		if(StringUtils.isBlank(CommonUtils.normalizeString(beanForm.getName()))){
			return "Vacancy name cannot be blank!";
		}
		
		int no = getIntegerParam(beanForm.getNoOfPositions());
		if (no <= 0) {
			return "No. of positions must be a positive integer!";
		}
		
		int managerId = CommonUtils.getEmpNumber(beanForm.getHiringManager());
		if (managerId <= 0) {
			return "Hiring manager is empty or invalid!";
		}
		
		int eduWeight = beanForm.getEduWeight();
		int langWeight = beanForm.getLangWeight();
		int skillWeight = beanForm.getSkillWeight();
		int licenseWeight = beanForm.getLicenseWeight();
		
		if (eduWeight < 0) {
			return "Education weight must be a non-negative integer!";
		}
		if (langWeight < 0) {
			return "Language weight must be a non-negative integer!";
		}
		if (skillWeight < 0) {
			return "Skill weight must be a non-negative integer!";
		}
		if (licenseWeight < 0) {
			return "License weight must be a non-negative integer!";
		}
		if (eduWeight + langWeight + skillWeight + licenseWeight != 100) {
			return "Weights must be non-negative integers and their sum must be 100!";
		}
		
		FormFile attachFile = beanForm.getAttachFile();
		if(attachFile != null && StringUtils.isNotBlank(attachFile.getFileName())){
			if(attachFile.getFileSize() > 2097152){
				return "Attached file size is too large! (< 2 MB required!)";
			} else if(!"application/pdf".equalsIgnoreCase(attachFile.getContentType())
					&& !"application/msword".equalsIgnoreCase(attachFile.getContentType())
					&& !"application/vnd.openxmlformats-officedocument.wordprocessingml.document".equalsIgnoreCase(attachFile.getContentType())){
				return "Attached file type is not valid! (Only .pdf, .doc or .docx files are accepted!)";
			}
		}

		return StringConstants.BLANK;
	}
}